import { Discount, DiscountType, OrderItem, OrderService } from "@mallfoundry/order"
import { Alert, InputNumber, Modal, Table, Tooltip, Typography } from "antd"
import { ColumnProps } from "antd/es/table"
import Decimal from "decimal.js"
import * as _ from "lodash"
import * as React from "react"
import { useEffect, useState } from "react"
import classes from "./order-discounts.module.scss"

const { Text } = Typography

interface OrderDiscountsModalProps {
  visible: boolean
  orderId: string,
  items?: OrderItem[]
  onCancel?: () => void
  onChanged?: () => void
}

export function OrderDiscountsModal(props: OrderDiscountsModalProps) {
  const { visible, orderId, onCancel, onChanged } = props
  const { items: oldItems = [] } = props

  const [items, setItems] = useState<OrderItem[]>([])
  const [subtotalAmount, setSubtotalAmount] = useState(0)
  const [loading, setLoading] = useState(false)

  useEffect(() => {
    setItems(_.map(props.items, item => _.assign(new OrderItem(), item)))
    setSubtotalAmount(_.map(props.items)
      .reduce((subtotalAmount, item) => Decimal.add(subtotalAmount, _.isUndefined(item.subtotalAmount) ? 0 : item.subtotalAmount).toNumber(), 0))
  }, [props.items])

  function refreshItems() {
    setItems(_.map(items, item => _.assign(new OrderItem(), item)))
  }

  function changeDiscountAmount(item: OrderItem, amount: number) {
    const { subtotalAmount = 0 } = item
    if ((0 - subtotalAmount) <= amount) {
      item.discountTotalPrice = amount
      refreshItems()
    }
  }

  function changeShippingCost(item: OrderItem, discountShippingCost: number) {
    const { shippingCost = 0 } = item
    item.discountShippingCost = discountShippingCost - shippingCost
    refreshItems()
  }

  const columns: ColumnProps<OrderItem>[] = [
    {
      title: "商品",
      dataIndex: "name",
      key: "name",
      width: "140px",
      render: (text: string) =>
        <Tooltip title={text}>
          <Text style={{ width: "140px" }} ellipsis children={text}/>
        </Tooltip>,
    },
    {
      title: "单价(元)",
      dataIndex: "price",
      key: "price",
      align: "center",
    },
    {
      title: "数量",
      dataIndex: "quantity",
      key: "quantity",
      align: "center",
    },
    {
      title: "总价(元)",
      dataIndex: "totalPrice",
      key: "totalPrice",
      align: "center",
    },
    {
      title: "小计(元)",
      dataIndex: "subtotalAmount",
      key: "subtotalAmount",
      align: "center",
    },
    {
      title: "涨价或减价(元)",
      dataIndex: "discountTotalPrice",
      key: "discountTotalPrice",
      width: "110px",
      render: (amount, item) => {
        const { totalPrice = 0 } = item
        return (
          <InputNumber precision={2}
                       value={amount}
                       min={0 - totalPrice}
                       onChange={_.curry(changeDiscountAmount)(item)}/>
        )
      },
    },
    {
      title: "运费(元)",
      dataIndex: "discountShippingCost",
      key: "discountShippingCost",
      width: "110px",
      render: (discountShippingCost, item) =>
        <InputNumber precision={2}
                     value={item.shippingCost + discountShippingCost}
                     min={0}
                     onChange={_.curry(changeShippingCost)(item)}/>,
    },
    {
      title: "实付金额(元)",
      dataIndex: "actualAmount",
      key: "actualAmount",
      align: "center",
      width: "110px",
      render: (amount, item) => {
        const {
          totalPrice = 0,
          shippingCost = 0,
          discountTotalPrice = 0,
          discountShippingCost = 0,
        } = item
        return (
          new Decimal(totalPrice)
            .add(shippingCost)
            .add(discountTotalPrice)
            .add(discountShippingCost)
            .toNumber()
        )
      },
    },
  ]

  function createOrderDiscounts() {
    return _.transform(oldItems, (discounts, oldItem) => {
      const item = _.find(items, item => item.id === oldItem.id)
      if (item) {
        if (item.discountTotalPrice !== oldItem.discountTotalPrice) {
          const discountTotalPrice = new Discount()
          discountTotalPrice.itemId = item.id
          discountTotalPrice.type = DiscountType.TotalPrice
          discountTotalPrice.amountDelta = item.discountTotalPrice
          discounts.push(discountTotalPrice)
        }

        if (item.discountShippingCost !== oldItem.discountShippingCost) {
          const discountTotalPrice = new Discount()
          discountTotalPrice.itemId = item.id
          discountTotalPrice.type = DiscountType.ShippingCost
          discountTotalPrice.amountDelta = item.discountShippingCost
          discounts.push(discountTotalPrice)
        }
      }
      return discounts
    }, [] as Discount[])
  }

  const discounts = createOrderDiscounts()

  function handleOk() {
    if (!_.isEmpty(discounts)) {
      setLoading(true)
      OrderService.discountOrder(orderId, discounts)
        .then(onChanged)
        .finally(() => setLoading(false))
    }
  }

  return (<Modal className={classes.orderDiscountsModal}
                 visible={visible}
                 maskClosable={false}
                 confirmLoading={loading}
                 onCancel={onCancel}
                 okButtonProps={{
                   disabled: _.isEmpty(discounts),
                 }}
                 onOk={handleOk}
                 width={840} title={`订单原价(含运费)：${subtotalAmount} 元`}>
    <Alert message="只有订单未付款时才支持改价，改价后请联系买家刷新订单核实订单金额后再支付。" type="warning" showIcon/>
    <Table rowKey="id" size="small" columns={columns} dataSource={items} pagination={false}/>
  </Modal>)
}
